package mqtt

import (
	"encoding/json"
	"fmt"
	"log"
)

// Publisher 数据发布器
type Publisher struct {
	client *Client
}

// NewPublisher 创建发布器
func NewPublisher(client *Client) *Publisher {
	return &Publisher{
		client: client,
	}
}

// PublishSensorData 发布传感器数据
// Topic 格式: sensors/{device_id}/{sensor_type}
func (p *Publisher) PublishSensorData(data *SensorData) error {
	topic := fmt.Sprintf("sensors/%s/%s", data.DeviceID, data.SensorType)

	payload, err := json.Marshal(data)
	if err != nil {
		return fmt.Errorf("序列化数据失败: %v", err)
	}

	if err := p.client.Publish(topic, payload); err != nil {
		return err
	}

	log.Printf("📤 [MQTT] 发布传感器数据: %s - %s: %.2f %s",
		data.DeviceID, data.SensorType, data.Value, data.Unit)

	return nil
}

// PublishDeviceStatus 发布设备状态
// Topic 格式: devices/{device_id}/status
func (p *Publisher) PublishDeviceStatus(status *DeviceStatus) error {
	topic := fmt.Sprintf("devices/%s/status", status.DeviceID)

	payload, err := json.Marshal(status)
	if err != nil {
		return fmt.Errorf("序列化状态失败: %v", err)
	}

	if err := p.client.Publish(topic, payload); err != nil {
		return err
	}

	log.Printf("📤 [MQTT] 发布设备状态: %s - %s", status.DeviceID, status.Status)

	return nil
}

// PublishAlert 发布告警
// Topic 格式: alerts/{device_id}/{severity}
func (p *Publisher) PublishAlert(alert *Alert) error {
	topic := fmt.Sprintf("alerts/%s/%s", alert.DeviceID, alert.Severity)

	payload, err := json.Marshal(alert)
	if err != nil {
		return fmt.Errorf("序列化告警失败: %v", err)
	}

	if err := p.client.Publish(topic, payload); err != nil {
		return err
	}

	log.Printf("🚨 [MQTT] 发布告警: %s - %s - %s",
		alert.DeviceID, alert.Severity, alert.Message)

	return nil
}

// PublishHeartbeat 发布心跳
// Topic 格式: devices/{device_id}/heartbeat
func (p *Publisher) PublishHeartbeat(deviceID string, metadata map[string]interface{}) error {
	topic := fmt.Sprintf("devices/%s/heartbeat", deviceID)

	heartbeat := map[string]interface{}{
		"device_id": deviceID,
		"timestamp": "",
		"metadata":  metadata,
	}

	payload, err := json.Marshal(heartbeat)
	if err != nil {
		return fmt.Errorf("序列化心跳失败: %v", err)
	}

	if err := p.client.Publish(topic, payload); err != nil {
		return err
	}

	return nil
}
